
fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Get input from CLI
    let args: Vec<String> = std::env::args().collect();
    let name = &args[1];
    let age = &args[2];

    let mut conn = postgres::Client::connect("host=localhost user=postgres", postgres::NoTls)?;

    conn.execute(       // $ sql-sink
        "CREATE TABLE person (
            id SERIAL PRIMARY KEY,
            name VARCHAR NOT NULL,
            age INT NOT NULL
        )",
        &[],
    )?;

    let query = format!("INSERT INTO person (name, age) VALUES ('{}', '{}')", name, age);
    let query2 = "INSERT INTO person (id) VALUES ($1)";

    conn.execute(query.as_str(), &[])?;     // $ sql-sink
    conn.batch_execute(query.as_str())?;    // $ sql-sink

    conn.prepare(query.as_str())?;          // $ sql-sink
    conn.prepare_typed(query2, &[postgres::types::Type::INT4])?; // $ sql-sink

    conn.query(query.as_str(), &[])?;       // $ sql-sink
    conn.query_one(query.as_str(), &[])?;   // $ sql-sink
    conn.query_opt(query.as_str(), &[])?;   // $ sql-sink
    let params: Vec<i32> = vec![0];
    conn.query_raw(query.as_str(), params)?;        // $ sql-sink
    conn.query_typed(query.as_str(), &[])?;         // $ sql-sink
    let params: Vec<(i32, postgres::types::Type)> = vec![(0, postgres::types::Type::INT4)];
    conn.query_typed_raw(query2, params)?;  // $ sql-sink

    for row in &conn.query("SELECT id, name, age FROM person", &[])? {  // $ sql-sink
        let id: i32 = row.get("id"); // $ database-read
        let name: &str = row.try_get("name")?; // $ database-read
        let age: i32 = row.try_get("age").unwrap(); // $ database-read
        println!("found person: {} {} {}", id, name, age);
    }

    for message in &conn.simple_query("SELECT id, name, age FROM person")? {  // $ sql-sink
        if let postgres::SimpleQueryMessage::Row(row) = message {
            let id: i32 = row.get(0).unwrap().parse().unwrap(); // $ database-read
            let name: &str = row.get(1).unwrap(); // $ database-read
            let age: i32 = row.get(2).unwrap().parse().unwrap(); // $ database-read
            println!("found person: {} {} {}", id, name, age);
        }
    }

    Ok(())
}
